package com.lfc.flowable.service.impl;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lfc.flowable.domian.LeaveApply;
import com.lfc.flowable.mapper.LeaveApplyMapper;
import com.lfc.flowable.service.LeaveApplyService;
import jakarta.annotation.Resource;
import org.flowable.bpmn.model.BpmnModel;
import org.flowable.bpmn.model.UserTask;
import org.flowable.engine.ProcessEngine;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.task.api.Task;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class LeaveApplyServiceImpl extends ServiceImpl<LeaveApplyMapper, LeaveApply> implements LeaveApplyService {

    @Resource
    private ProcessEngine processEngine;

    /**
     * MyBatis-Plus 的 save() 方法
     *
     * @param leaveApply
     * @return
     */
    @Override
    public boolean submitLeave(LeaveApply leaveApply) {
        return this.save(leaveApply);
    }

    /**
     * 分页查询请假列表
     *
     * @param pageNum  当前页
     * @param pageSize 每页条数
     * @param userId   筛选条件（可选）
     */
    @Override
    public Page<LeaveApply> getLeavePage(Integer pageNum, Integer pageSize, String userId) {
        // 1. 构建分页参数
        Page<LeaveApply> page = new Page<>(pageNum, pageSize);

        // 2. 构建查询条件（按需添加）
        LambdaQueryWrapper<LeaveApply> queryWrapper = new LambdaQueryWrapper<>();
        if (userId != null) {
            queryWrapper.eq(LeaveApply::getUserId, userId);
        }
        queryWrapper.orderByDesc(LeaveApply::getApplyTime); // 按申请时间倒序

        Page<LeaveApply> leaveApplyPage = this.page(page, queryWrapper);
        for (LeaveApply leaveApply : leaveApplyPage.getRecords()) {
            // 通过businessKey反向查询
            ProcessInstance instance = processEngine.getRuntimeService().createProcessInstanceQuery()
                    .processInstanceBusinessKey(String.valueOf(leaveApply.getId()))
                    .singleResult();
            if (ObjectUtil.isNotEmpty(instance)) {
                leaveApply.setProcessInstanceId(instance.getId());
            }
        }

        // 3. 执行分页查询
        return leaveApplyPage;
    }

    @Override
    public void addLeaveApply(LeaveApply leaveApply) {
        submitLeave(leaveApply);
        // 发起请假流程
        HashMap<String, Object> variables = new HashMap<>();
        variables.put("applyuserid", leaveApply.getUserId());
        variables.put("applyusername", "徐慕凯");
        variables.put("deptleader", leaveApply.getDeptLeader());
        variables.put("deptleaderName", "徐慕凯");
        //默认使用最新版本
        processEngine.getRuntimeService().startProcessInstanceByKey("leave", String.valueOf(leaveApply.getId()), variables);
    }

    @Override
    public LeaveApply getLeaveApply(String id) {
        return this.getById(id);
    }

    @Override
    public LeaveApply getBusinessData(String taskId) {
        Task t = processEngine.getTaskService().createTaskQuery().taskId(taskId).singleResult();
        String processId = t.getProcessInstanceId();
        ProcessInstance p = processEngine.getRuntimeService().createProcessInstanceQuery().processInstanceId(processId).singleResult();
        LeaveApply apply = getLeaveApply(p.getBusinessKey());

        // 2. 获取流程定义
        BpmnModel bpmnModel = processEngine.getRepositoryService().getBpmnModel(t.getProcessDefinitionId());

        // 3. 找到当前任务节点
        UserTask userTask = (UserTask) bpmnModel.getFlowElement(t.getTaskDefinitionKey());

        // 4. 获取候选人配置
        List<String> candidateUsers = new ArrayList<>();
        if (userTask.getCandidateUsers() != null) {
            candidateUsers.addAll(userTask.getCandidateUsers());
        }

        // 5. 获取候选组配置
        if (userTask.getCandidateGroups() != null) {
            // 可以将组转换为实际用户（需实现自己的组服务）
            userTask.getCandidateGroups().forEach(group -> {
                //todo: 获取组中的用户
//                candidateUsers.addAll(userGroupService.getUsersByGroup(group));
            });
        }
        // 2. 查询业务数据
        return apply;
    }

    @Override
    public void completeTask(String taskId, Map<String, Object> variables) {
        processEngine.getTaskService().setAssignee(taskId, "xmkk");
        // 查出流程实例id
        String processInstanceId = processEngine.getTaskService().createTaskQuery().taskId(taskId).singleResult().getProcessInstanceId();
        if (variables == null) {
            processEngine.getTaskService().complete(taskId);
        } else {
            // 添加审批意见
            if (variables.get("comment") != null) {
                processEngine.getTaskService().addComment(taskId, processInstanceId, (String) variables.get("comment"));
                variables.remove("comment");
            }
//            processEngine.getTaskService().setVariableLocal(taskId, "approvalResult", result);
            processEngine.getTaskService().complete(taskId, variables);
        }
    }

    @Override
    public void deleteLeaveApplyByIds(String ids) {
        String[] keys = Convert.toStrArray(ids);
        for (String key : keys) {
            ProcessInstance process = processEngine.getRuntimeService().createProcessInstanceQuery().processDefinitionKey("leave").processInstanceBusinessKey(key).singleResult();
            try {
                processEngine.getRuntimeService().deleteProcessInstance(process.getId(), "删除");
            } catch (Exception e) {
                e.printStackTrace();
            }
            this.removeById(key);
        }
    }
}
